
#include "AtomNumFilter.hh"

#include "AtomNumFilterMsgr.hh"
#include "G4ParticleDefinition.hh"
#include "G4Step.hh"
#include "G4Track.hh"

//#include <fstream> //debug
//static std::ofstream flog("filter_debug.log", std::ios::app); //debug

// ========================================================
// 通过这个filter实现如下分类:
// 1. Z = targetZ 且 cat = "primary" 的作为primary粒子组
// 2. Z = targetZ 且 cat = "nonprimary" 的作为一组
// 3. Z = 1, 2, 3, 4, 5... Zmax 的每个粒子单独作为一组, Zmax可以定一个数
// 5. Z > Zmax 的粒子 以及 其他非 ion的(比如电子、光子等等) 作为一组
//
// ========================================================

AtomNumFilter::AtomNumFilter(const G4String& name, G4int targetZ, G4int Zmax, const G4String& cat)
    : G4VSDFilter(name),
      _fTargetZ(targetZ),
      _fZmax(Zmax),
      _fCat(cat)  //, _sfMessenger(nullptr)
{
    //_sfMessenger = new AtomNumFilterMsgr(this);
    G4cout << "Filter created: " << name << G4endl;
}

// 拷贝构造函数, 用于复制实例
//AtomNumFilter::AtomNumFilter(const AtomNumFilter& a)
//  : G4VSDFilter(a.fName), _fTargetZ(a._fTargetZ), _fZmax(a._fZmax), _fCat(a._fCat)
//{}

AtomNumFilter::~AtomNumFilter()
{
    //delete _sfMessenger;
}

G4bool AtomNumFilter::Accept(const G4Step* step) const
{
    //flog << "=== Filter Entered ===" << std::endl;
    //flog.flush();  // Force immediate write
    //flog << "AtomNumFilter Accept method log..." << std::endl;
    //G4cout << "AtomNumFilter Accept method executing..." << G4endl;
    //G4cout << "targetZ: " << _fTargetZ << ", Zmax: " << _fZmax << ", cat: " << _fCat << G4endl;
    const G4Track* track = step->GetTrack();
    const G4ParticleDefinition* particle = track->GetDefinition();

    /*
  G4cout << "Filter checking: " << particle->GetParticleName()
         << " Z=" << particle->GetAtomicNumber()
         << " ParentID=" << track->GetParentID()
         << " ParticleType=" << particle->GetParticleType()
         << " Charge=" << particle->GetPDGCharge() << G4endl;
  */

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 不做任何过滤
    if (_fCat == "any")
    {
        return true;
    }

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx lepton, gamma, meson, neutron等 以及 Z > 入射粒子Z的nucleus
    if (_fCat == "other")
    {
        const bool isProton = particle->GetParticleName() == "proton";
        const bool isLightNucleus = (particle->GetParticleType() == "nucleus" && particle->GetAtomicNumber() <= _fZmax);
        const bool mainParticles = isProton || isLightNucleus;
        const bool isOthers = !mainParticles;
        if (isOthers)
        {
            return true;
        }
        return false;
    }

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 注意proton的particleType是baryon, Z=1
    // 如果不是"nucleus"或者“是但是原子序数超过Zmax” 则接受
    /*
  if (particle->GetParticleType() != "nucleus" || (particle->GetParticleType() == "nucleus" && particle->GetAtomicNumber() > _fZmax))
  {
      //G4cout << "not ion: " << particle->GetParticleType() << G4endl;
      return true;
  }
  */

    //00000000000000000000000000000000000000000000000 Z <= Zmax 的 main particles

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 判断粒子的原子序数是否等于目标值
    if (_fCat == "target")
    {
        if (particle->GetAtomicNumber() != _fTargetZ)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 是否primary粒子的过滤：
    if (_fCat == "primary")
    {
        // 只接受 primary 粒子
        //G4cout << "WENXIAO filter: primary particle" << G4endl;
        if (track->GetParentID() != 0) return false;
    }
    else if (_fCat == "nonprimary")
    {
        // 只接受非 primary 粒子
        //G4cout << "WENXIAO filter: nonprimary particle" << G4endl;
        if (track->GetParentID() == 0) return false;
    }

    return true;
}

/*
void AtomNumFilter::SetAtomNumFilterArgs(G4int targetZ, G4int Zmax, const G4String& cat) {
  _fTargetZ = targetZ;
  _fZmax    = Zmax;
  _fCat     = cat;
}
*/

//void AtomNumFilter::show() {
//  G4cout << << G4endl;
//}